<?php
namespace app\index\controller\practice;

use app\common\model\admin\AccountModel;
use app\common\model\index\CategoryModel;
use app\common\model\index\NavModel;
use app\common\model\paths\ClassModel;
use app\common\model\paths\ClassTaskModel;
use app\common\model\paths\EmployInfoModel;
use app\common\model\paths\EmployLogModel;
use app\common\model\paths\TaskChapterModel;
use app\common\model\paths\TaskModel;
use app\common\model\paths\UserClassModel;
use app\common\model\paths\UserStudyGoldModel;
use app\index\controller\BaseIndex;
use think\admin\extend\DataExtend;
use think\admin\model\SystemUser;
use think\facade\Db;
use think\facade\Validate;

/**
 * 实践课程
 * @package app\index\controller\practice
 * @author wangqinghui
 * @DateTime 2024-09-06 10:51:26
 */
class Course extends BaseIndex
{
    protected $check_login = true;
    /**
     * 列表页
     * @author wangqinghui
     * @DateTime 2024-09-09 09:23:48
     * @return void
     */
    public function index()
    {
        $this->title = lang('实践课程列表');
        $ct_id = (int)$this->request->get('ct_id', 0);
        $sub_ct_id = (int)$this->request->get('sub_ct_id', 0);
        // 获取导航数据
        $nav_id = (int)$this->request->get('nav_id', 0);
        $map = [
            ['status', '=', 1],// 启用
            ['id', '=', $nav_id],
        ];
        $navInfo = NavModel::mk()->where($map)->find();
        // 获取学科数据
        $map = [
            ['status', '=', 1],// 启用
        ];
        $category_list = CategoryModel::mk()->where($map)->order('sort desc,id asc')->select()->toArray();
        $category_data = DataExtend::arr2tree($category_list);
        // 获取所有子类
        $default_ct_list = [];
        if(!empty($category_data)){
            foreach ($category_data as $key => $value) {
                if(!empty($value['sub'])){
                    $default_ct_list = array_merge($default_ct_list, $value['sub']);
                }
            }
        }
        $category_data = array_column($category_data, null, 'id');
        $sub_category = $default_ct_list;
        if(!empty($category_data[$ct_id]['sub'])){
            $sub_category = $category_data[$ct_id]['sub'];
        }
        $this->fetch('index', ['nav' => $navInfo, 'category' => $category_data, 'sub_category' => $sub_category ?? [], 
        'page_size' => 16, 'query' => ['ct_id' => $ct_id, 'sub_ct_id' => $sub_ct_id], 'default_sct' => $default_ct_list]);
    }

    /**
     * 获取课程列表数据
     * @author wangqinghui
     * @DateTime 2024-09-09 10:40:01
     * @return void
     */
    public function list()
    {
        // 搜索内容
        $key = trim($this->request->post('key', ''));
        // 分页
        $page = (int)$this->request->post('page', 1);
        $limit = (int)$this->request->post('limit', 16);
        // 分类
        $category_id = (int)$this->request->post('category_id', 0);
        $sub_category_id = (int)$this->request->post('sub_category_id', 0);

        // 获取实践课程数据
        $map = [
            ['status', '=', 1],// 启用
        ];
        if(!empty($key)){
            $map[] = ['title', 'like', "%{$key}%"];
        }
        if($category_id > 0){
            $map[] = ['category_id', '=', $category_id];
        }
        if($sub_category_id > 0){
            $map[] = ['sub_category_id', '=', $sub_category_id];
        }
        $total = TaskModel::mk()->where($map)->count();
        $list = TaskModel::mk()->where($map)->page($page,$limit)->order('id desc')->select()->toArray();
        // 获取课程作者信息
        $author_ids = array_column($list, 'user_id');
        $author_data = [];
        if(!empty($author_ids)){
            $map = [
                ['id',  'in', $author_ids],
                ['status', '=', 1],
                ['usertype', '=', 'teacher']
            ];
            $field = 'id,nickname,headimg';
            $author_data = SystemUser::mk()->where($map)->column($field, 'id');
        }

        // 获取课程所属平台
        $platform_ids = array_column($list, 'account_id');
        $platform_data = [];
        if(!empty($platform_ids)){
            $map = [
                ['id',  'in', $platform_ids],
                ['status', '=', 1],
                ['module', 'find in set', AccountModel::MODULE_SCHOOLS]
            ];
            $field = 'id,title';
            $platform_data = AccountModel::mk()->where($map)->column($field, 'id');
        }

        // 获取章节总数
        $ids = array_column($list, 'id');
        $map = [
            ['task_id', 'in', $ids],
            ['status', '=', 1],// 启用
            ['pid', '=', 0]
        ];
        $chapter_total_list = TaskChapterModel::mk()->field('task_id, count(id) as num')->where($map)->group('task_id')->select()->toArray();
        $chapter_total = array_column($chapter_total_list, 'num', 'task_id');
        foreach ($list as $key => $item){
            $list[$key]['chapter_total'] = !empty($chapter_total[$item['id']]) ? $chapter_total[$item['id']] : 0;
            $list[$key]['auther'] = !empty($author_data[$item['user_id']]['nickname']) ? $author_data[$item['user_id']]['nickname'] : '';
            $list[$key]['platform'] = !empty($platform_data[$item['account_id']]['title']) ? $platform_data[$item['account_id']]['title'] : '';
        }
        $this->success('获取成功', ['total' => $total, 'list' => $list]);
    }

    /**
     * 实践课程详情
     * @author wangqinghui
     * @DateTime 2024-09-09 18:34:05
     * @return void
     */
    public function detail()
    {
        $this->title = lang('实践课程详情');
        $id = (int)$this->request->get('id', 0);
        $ret = UserClassModel::mk()->checkUserClass($this->user_id, $id);
        $is_join = false;
        if(!empty($ret['code']) && ($ret['code'] == 1)){
            $is_join = true;
        }
        // 获取课程信息
        $map = [
            ['id', '=', $id],
            ['status', '=', 1]// 启用
        ];
        $info = TaskModel::mk()->where($map)->find();
        // 获取学习分数
        $map = [
            ['task_id', 'in', $id],
            ['status', '=', 1],// 启用
        ];
        $chapter_list = TaskChapterModel::mk()->field('id,task_id,pid,status,type,duration,score,employ_id')->where($map)->select()->toArray();
        $info['chapter_total'] = $info['study_score_total'] = 0;
        $employ_ids = [];
        if(!empty($chapter_list)){
            foreach ($chapter_list as $key => $value) {
                // 获取总章节
                if(isset($value['pid']) && $value['pid'] == 0){
                    $info['chapter_total'] += 1;
                }
                if(isset($value['type']) && $value['type'] == 3){ //实战
                    $employ_ids[] = $value['employ_id'];
                }else{
                    $info['study_score_total'] += $value['score'];
                }
            }
        }
        

        // 获取课程关卡信息
        $map = [
            ['app_id', 'in', $employ_ids],
            ['status', '=', 1],// 启用
            ['pid', '=', 0],
            ['level', '=', 1] // 关卡
        ];
        $employ_detail_list = EmployInfoModel::mk()->where($map)->order('id asc')->select()->toArray();
        $info['employ_total'] = count($employ_detail_list) ?? 0;
        $info['employ_gold_total'] = !empty($employ_detail_list) ? array_sum(array_column($employ_detail_list, 'gold')) : 0;

        // 获取课程所属班级
        $map = [
            ['task_id', '=', $id]
        ];
        $class_ids = ClassTaskModel::mk()->where($map)->column('class_id');
        $classList = [];
        if(!empty($class_ids)){
            // 获取班级信息
            $map = [
                ['id', 'in', $class_ids],
                ['status', '=', 1],// 启用状态
            ];
            $field = 'id,account_id,user_id,name';
            $classList = ClassModel::mk()->with(['user'])->field($field)->where($map)->select()->toArray();
            // 获取平台信息
            $platform_ids = array_column($classList, 'account_id');
            $paltform_data = [];
            if(!empty($platform_ids)){
                $map = [
                    ['id',      'in',   $platform_ids],
                    ['module',  'find in set', AccountModel::MODULE_SCHOOLS]
                ];
                $paltform_data = AccountModel::mk()->where($map)->column('title', 'id');
            }
            if(!empty($classList)){
                foreach ($classList as $key => $value) {
                    $classList[$key]['platform_name'] = !empty($paltform_data[$value['account_id']]) ? $paltform_data[$value['account_id']] : '';
                }
            }
        }

        // 获取课程作者
        $author_data = [];
        if(!empty($info['user_id'])){
            $map = [
                ['id', '=', $info['user_id']],
                ['status', '=', 1],// 启用状态
            ];
            $field = 'id,nickname,headimg';
            $author_data = SystemUser::mk()->field($field)->where($map)->select()->toArray();
        }
        $this->fetch('detail', ['info' => $info, 'is_join' => $is_join, 'classList' => $classList, 'author_data' => $author_data]);
    }

    /**
     * 获取章节列表
     * @author wangqinghui
     * @DateTime 2024-09-10 09:13:25
     * @return void
     */
    public function chapter_list()
    {
        $id = (int)$this->request->post('id', 0);
        if(empty($id) || ($id <= 0)){
            $this->error('课程信息有误');
        }
        // 校验用户是否加入班级
        $ret = UserClassModel::mk()->checkUserClass($this->user_id, $id);
        if(empty($ret['code']) || $ret['code'] != 1){
            $this->error($ret['msg'], $ret['data'], $ret['code']);
        }
        // 获取章节列表
        $map = [
            ['task_id', '=', $id],
            ['status', '=', 1]// 启用
        ];
        $list = TaskChapterModel::mk()->where($map)->order('id asc')->select()->toArray();
        $data = DataExtend::arr2tree($list);
        $this->success('获取成功', $data);
    }

    /**
     * 申请加入班级
     * @author wangqinghui
     * @DateTime 2024-09-14 11:39:46
     * @return void
     */
    public function jonClass()
    {
        $class_id = (int)$this->request->post('c_id', 0);
        $apply_reason = $this->request->post('reason', '');
        if(empty($class_id) || ($class_id <= 0)){
            $this->error('班级信息有误');
        }
        if(empty($this->user_id) || ($this->user_id <= 0)){
            $this->error('请先登录', sysuri('login/index'), -1200);
        }
        // 需要完善个人信息
        $this->checkCompleteUser();
        if($this->need_complete_user){
            $this->error('请先完善个人信息', sysuri('/index/user.profile'), -1201);
        }
        // 检查班级信息
        $map = [
            ['id', '=', $class_id],
            ['status', '=', 1]
        ];
        $class_info = ClassModel::mk()->where($map)->find();
        if(empty($class_info)){
            $this->error('班级信息有误');
        }

        // 检查是否已经申请过
        $map = [
            ['index_user_id', '=', $this->user_id],
            ['class_id', '=', $class_id],
        ];
        $info = UserClassModel::mk()->where($map)->order('id desc')->find();
        if(!empty($info)){
            if($info['status'] == UserClassModel::STATUS_AGREE){
                $this->error('您已加入班级');
            }elseif($info['status'] == UserClassModel::STATUS_APPLY){
                $this->error('您已申请加入班级,请等待审核');
            }
        }
        $rule = [
            'apply_reason|申请理由' => 'length:2,200'
        ];
        $validate = Validate::rule($rule);
        $data = [
            'apply_reason'  => $apply_reason
        ];
        if(!$validate->check($data)){
            $this->error($validate->getError());
        }
        // 创建申请记录
        $addData = [
            'index_user_id' => $this->user_id,
            'class_id' => $class_id,
            'status' => UserClassModel::STATUS_APPLY,
            'platform_id'   => $class_info['account_id'],
            'user_id'   => $class_info['user_id'],
            'create_at' => date('Y-m-d H:i:s'),
            'apply_reason'  => $apply_reason
        ];
        $user_class_id = UserClassModel::mk()->insertGetId($addData);
        if(empty($user_class_id) || ($user_class_id <= 0)){
            $this->error('申请失败');
        }
        $this->success('已成功申请加入班级,请等待审核');
    }

    /**
     * 开始学习
     * @author wangqinghui
     * @DateTime 2024-09-18 09:57:38
     * @return void
     */
    public function study()
    {
        $this->title = lang('学习');
        $task_id = (int)$this->request->get('task_id', 0);
        $chapter_id = (int)$this->request->get('cp_id', 0);
        $menu = [];
        // 校验用户是否加入班级
        $ret = UserClassModel::mk()->checkUserClass($this->user_id, $task_id);
        if(empty($ret['code']) || $ret['code'] != 1){
            $this->fetch('study', ['menu' => $menu, 'task_id' => $task_id, 'cp_id' => $chapter_id, 'err_msg' => $ret['msg']]);
        }
        if(!empty($task_id) && ($task_id > 0)){
            // 获取章节资源
            $map = [
                ['task_id', '=', $task_id],// 课程ID
                ['status',  '=',    1],// 启用
            ];
            $list = TaskChapterModel::mk()->where($map)->order('id asc')->select()->toArray();
            $menu = DataExtend::arr2tree($list);
        }
        $this->fetch('study', ['menu' => $menu, 'task_id' => $task_id, 'cp_id' => $chapter_id]);
    }

    /**
     * 学习记录
     * @author wangqinghui
     * @DateTime 2024-09-24 18:02:45
     * @return void
     */
    public function study_log()
    {
        $task_id = (int)$this->request->post('task_id', 0);
        $cp_id = (int)$this->request->post('cp_id', 0);
        $duration = (int)$this->request->post('duration', 0);
        if(empty($task_id) || ($task_id <= 0)){
            $this->error('课程信息有误');
        }
        if(empty($cp_id) || ($cp_id <= 0)){
            $this->error('章节信息有误');
        }
        if(empty($duration) || ($duration <= 0)){
            $this->success('学习记录成功');
        }
        if(empty($this->user_id) || ($this->user_id <= 0)){
            $this->error('请登录用户');
        }
        // 获取章节信息
        $chapter_info = TaskChapterModel::mk()->where(['id' => $cp_id])->find();
        if(empty($chapter_info)){
            $this->error('章节信息有误');
        }
        // 获取是否已经学习过
        $map = [
            ['type',    '=',    2], // 学习记录类型
            ['index_user_id',   '=',    $this->user_id],// 用户ID
            ['task_id',         '=',    $task_id],// 课程ID
            ['levels_id', '=',    $cp_id],// 章节ID
            ['is_finished',    '=',    1]// 学习完成
        ];
        $study_list = EmployLogModel::mk()->field('id')->where($map)->select()->toArray();
        if(!empty($study_list)){
            $this->success('您已经学习过该章节');
        }
        $is_finish = $score = 0;
        if(($duration - ($chapter_info['duration'] * 60)) >= 0){
            $score = $chapter_info['score'] ?? 0;
            // 已完成学习
            $is_finish = 1;
            // 记录学分
            $study_gold_ids = array_column($study_list, 'id') ?? [];
            $this->_record_study($task_id, $cp_id, $chapter_info['pid'], $score, $study_gold_ids);
        }

        $addData = [
            'index_user_id' => $this->user_id,// 用户
            'task_id'   => $task_id,// 课程
            'levels_id'    => $cp_id,// 章节
            'duration'  => $duration,// 时长
            'gold' => $score,// 分数
            'type'  => 2,// 类型 学习
            'is_finished'  => $is_finish,// 是否完成
        ];
        $log_mol = EmployLogModel::create($addData);
        if(empty($log_mol->id) || ($log_mol->id <= 0)){
            $this->error('学习记录失败');
        }
        $this->success('学习记录成功');
    }

    /**
     * 记录学习成绩
     * @author wangqinghui
     * @DateTime 2024-09-29 15:23:20
     * @param integer $task_id
     * @param integer $cp_id
     * @param integer $cp_pid
     * @param integer $score
     * @param array $study_gold_ids
     * @return void
     */
    protected function _record_study(int $task_id, int $cp_id, int $cp_pid, int $score, array $study_gold_ids)
    {
        if(!empty($study_gold_ids)){
            $update_data = [
                'task_gold' => $score,
                'total_gold' => Db::raw('task_gold+employ_gold')
            ];
            $ret = UserStudyGoldModel::mk()->where('id', 'in', $study_gold_ids)->update($update_data);
            if($ret < 0){
                $this->error('更新学习分数失败');
            }
        }else{
            $class_ids = UserClassModel::mk()->getMyTaskClasses($this->user_id, $task_id);
            list($class_ids, $class_data) = UserClassModel::mk()->getMyTaskClasses($this->user_id, $task_id);
            if(!empty($class_ids)){
                $add_data = [];
                foreach ($class_ids as $key => $value) {
                    $add_data[] = [
                        'platform_id'   => !empty($class_data[$value]['platform_id']) ? $class_data[$value]['platform_id'] : 0,
                        'user_id'       => !empty($class_data[$value]['user_id']) ? $class_data[$value]['user_id'] : 0,
                        'index_user_id' => $this->user_id,
                        'class_id'  => $value,
                        'task_id' => $task_id,
                        'task_chapter_id' => $cp_id,
                        'task_chapter_pid' => $cp_pid,
                        'task_gold' => $score,
                        'total_gold' => Db::raw('task_gold+employ_gold')
                    ];
                }
                $ret = UserStudyGoldModel::mk()->insertAll($add_data);
                if($ret <= 0){
                    $this->error('添加学习分数失败');
                }
            }else{
                $this->error('班级信息有误');
            }
        }
    }

    /**
     * 获取视频地址
     * @author wangqinghui
     * @DateTime 2024-10-08 15:18:48
     * @return void
     */
    public function getInfo()
    {
        $cid = $this->request->get('cid', 0);
        if(empty($cid) || ($cid <= 0)){
            $this->error('章节内容有误');
        }
        $info = TaskChapterModel::mk()->field('id,type,task_id,title,content')->where(['id' => $cid])->find();
        if(empty($info)){
            $this->error('章节内容有误');
        }
        if(!empty($info['content'])){
            if(strpos($info['content'], 'http://') === false && strpos($info['content'], 'https://') === false){
                $info['content'] = $this->request->domain().'/'.$info['content'];
            }
            $info['is_office'] = 0;
            if($info['type'] == 1){// 资料
                $info['is_office'] = (int)isOfficeFile($info['content']);
            }
        }
        $this->fetch('info', ['info' => $info->toArray()]);
    }
}